package liuch.threadPool;

import java.util.concurrent.*;

/**
 * @author 17101651
 * @ClassName Future_FutureTask_Raunble_Callable
 * @Description A   调度执行线程单元的三种形式Thread，Runnable实现run()方法，Callable实现 T call()有返回值。
 * <p>
 * B   Runnable，可以被Thread包装，启动线程执行，也能被ExecutorService调度；Callable只能用ExecutorService作为调度容器。
 * <p>
 * C   Future 主要用于查看任务进行的状态(isDone()任务是否完成)，结果。使用get()方法获取结果时，当前线程处于阻塞状态（如果任务中抛出异常，get()方法也会出现异常）。
 * <p>
 * D   FutureTask，是Future和Runnable，Callable的混合体。
 * @data 2018年07月18日
 */
public class Future_FutureTask_Raunble_Callable {
    static void callable() {
        Callable<String> task = new Callable<String>() {
            @Override
            public String call() throws Exception {
                try {
                    Long start = System.currentTimeMillis();
                    System.out.println("Start callable task" + start);
                    Thread.sleep(1000 * 2);
                    System.out.println("End callable task");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return "time" + System.currentTimeMillis();
            }
        };

        // 采用ExecutorService执行future
        FutureTask<String> future = new FutureTask<String>(task);
        FutureTask<String> future2 = new FutureTask<String>(task);
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(future);
        executorService.submit(future2);
        executorService.shutdown();
        // futureTask运行在Thread中
        FutureTask<String> future3 = new FutureTask<String>(task);
        Thread thread = new Thread(future3);
        thread.start();
        try {
            System.out.println("future1:" + future.get());
            System.out.println("future2:" + future2.get());
            System.out.println("future3:" + future3.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    static void excutorService() {
        ExecutorService executor = Executors.newFixedThreadPool(1);

        try {
            /**
             * 1、callable通过Future能返回结果，并且future.get()能阻塞线程
             */
            Future<String> futureCall = executor.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    System.out.println("call running");
                    return "result=future1";
                }
            });

            /**
             * 2、runable通过Future返回结果为空
             */
            Future futureRunable = executor.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("runable running");
                }
            });

            /**
             * 3、模拟future可取消的线程
             */
            Future futureCancel = executor.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        while (true) {
                            Thread.sleep(50);
                            System.out.println("wait futureCancel");
                        }
                    } catch (InterruptedException e) {
                        System.out.println("futureCancel cancel " + e);
                    }
                }
            });
            Thread.sleep(10);

            /**
             * 4、future对于执行线程抛出异常的情况不返回结果
             */
            Future futureException = executor.submit(new Callable() {
                @Override
                public Object call() throws Exception {
                    throw new Exception("抛出异常");
                }
            });
            executor.shutdown();
            System.out.println("task1:" + futureCall.get());
            System.out.println("task2:" + futureRunable.get());
            System.out.println("futureCancel cancel " + futureCancel.cancel(true));
            System.out.println("futureException:" + futureException.get());

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
//        callable();
        excutorService();
    }
}
